package cn.yzgy.yzgyoa.common.utils;

/**
 * 十六进制数据处理工具
 *
 * @author Yqsen
 * @since 2019-8-22 11:36:45
 */
@SuppressWarnings({"unused","WeakerAccess"})
public class HexConvert {

    private static final String HEX_STRING = "0123456789ABCDEF";

    /**
     * 校验和计算
     * @param src 原始数据
     * @param startIndex 开始位置
     * @param endIndex 结束位置
     * @return 校验和
     */
    public static byte checkSum(byte[] src, int startIndex, int endIndex) {
        byte res = 0;
        for (int i = startIndex; i < endIndex; i++) {
            res += src[i];
        }
        return res;
    }

    /**
     * 将byte按照BCD方式转换为String
     * @param b byte
     * @return String
     */
    public static String byte2String(byte b) {
        String res = String.valueOf(HEX_STRING.charAt((b & 0xF0) >> 4));
        res += String.valueOf(HEX_STRING.charAt(b & 0x0F));
        return res;
    }

    /**
     * 将二进制字节数组转换为字符串
     * @param bytes 字节数组
     * @return 可读字符串
     */
    public static String binary2HexString(byte[] bytes) {
        String hexStr = "0123456789ABCDEF";
        StringBuilder result = new StringBuilder();
        String hex;
        for (byte b : bytes) {
            hex = String.valueOf(hexStr.charAt((b & 0xF0) >> 4));
            hex += String.valueOf(hexStr.charAt(b & 0x0F));
            result.append(hex).append(" ");
        }
        return result.toString().replace(" ","");
    }

    public static String convertStringToHex(String str) {

        char[] chars = str.toCharArray();

        StringBuffer hex = new StringBuffer();
        for (int i = 0; i < chars.length; i++) {
            hex.append(Integer.toHexString((int) chars[i]));
        }

        return hex.toString();
    }

    public static String convertHexToString(String hex) {

        StringBuilder sb = new StringBuilder();
        StringBuilder sb2 = new StringBuilder();

        for (int i = 0; i < hex.length() - 1; i += 2) {

            String s = hex.substring(i, (i + 2));
            int decimal = Integer.parseInt(s, 16);
            sb.append((char) decimal);
            sb2.append(decimal);
        }

        return sb.toString();
    }

    public static byte[] hexStringToBytes(String hexString) {
        if (hexString == null || hexString.equals("")) {
            return null;
        }
        // toUpperCase将字符串中的所有字符转换为大写
        hexString = hexString.toUpperCase();
        int length = hexString.length() / 2;
        // toCharArray将此字符串转换为一个新的字符数组。
        char[] hexChars = hexString.toCharArray();
        byte[] d = new byte[length];
        for (int i = 0; i < length; i++) {
            int pos = i * 2;
            d[i] = (byte) (charToByte(hexChars[pos]) << 4 | charToByte(hexChars[pos + 1]));
        }
        return d;
    }

    // 返回匹配字符
    private static byte charToByte(char c) {
        return (byte) "0123456789ABCDEF".indexOf(c);
    }

    // 将字节数组转换为short类型，即统计字符串长度
    public static short bytes2Short2(byte[] b) {
        short i = (short) (((b[1] & 0xff) << 8) | b[0] & 0xff);
        return i;
    }

    // 将字节数组转换为16进制字符串
    public static String BinaryToHexString(byte[] bytes) {
        String hexStr = "0123456789ABCDEF";
        String result = "";
        String hex = "";
        for (byte b : bytes) {
            hex = String.valueOf(hexStr.charAt((b & 0xF0) >> 4));
            hex += String.valueOf(hexStr.charAt(b & 0x0F));
            result += hex + " ";
        }
        return result;
    }


    // 获取bytes子集
    public static byte[] subByteArray(byte[] tmp, int startPos, int len) {
        byte[] res = new byte[len];
        for (int i = 0; i < len; i++) {
            res[i] = tmp[startPos + i];
        }
        return res;
    }

    // 将二进制bytes数组转换为十进制数
    public static int binaryToInt(byte[] bytes) {
        return Integer.parseInt(HexConvert.BinaryToHexString(bytesReverse(bytes)).replace(" ", ""), 16);
    }

    // BCD码转换为int
    public static int BCDToInt(byte[] BCDCodes) {
        return Integer.parseInt(HexConvert.BinaryToHexString(BCDCodes).replace(" ", ""), 16);
    }

    // BCD码转换为String
    public static String BCDToString(byte[] BCDCodes) {
        return HexConvert.BinaryToHexString(BCDCodes).replace(" ", "");
    }

    // 字节倒序返回
    public static byte[] bytesReverse(byte[] bytes) {
        byte[] newArry = new byte[bytes.length]; // 换成大端在前
        for (int i = 0; i < bytes.length; i++) {
            newArry[bytes.length - i - 1] = bytes[i];
        }
        return newArry;
    }
}
